package org.budo.dubbo.protocol.async.config;

import java.util.HashMap;

import org.budo.dubbo.protocol.async.BudoAsyncDubboProtocol;
import org.budo.dubbo.protocol.async.repository.AsyncRepository;
import org.budo.support.lang.util.StringUtil;
import org.springframework.beans.factory.InitializingBean;

import com.alibaba.dubbo.common.Constants;
import com.alibaba.dubbo.config.ApplicationConfig;
import com.alibaba.dubbo.config.ProtocolConfig;
import com.alibaba.dubbo.config.RegistryConfig;
import com.alibaba.dubbo.config.ServiceConfig;

import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;

/**
 * 收消息
 * 
 * @author limingwei
 * 
 * @see com.alibaba.dubbo.config.spring.ServiceBean
 */
@Slf4j
@Getter
@Setter
public class BudoAsyncServiceBean implements InitializingBean {
    private static final RegistryConfig NO_REGISTRY = new RegistryConfig(RegistryConfig.NO_AVAILABLE);

    private static final ApplicationConfig APPLICATION_BUDO_ASYNC = new ApplicationConfig("BudoAsyncServiceBean");

    private static final ProtocolConfig PROTOCOL_BUDO_ASYNC = new ProtocolConfig("budo-async");

    private Class<?> interfaceType;

    private String destinationName = "";

    private Object instance;

    private String asyncRepositoryBeanName;

    private String serialization = BudoAsyncDubboProtocol.DEFAULT_SERIALIZATION;

    @Override
    public void afterPropertiesSet() throws Exception {
        ServiceConfig<Object> serviceConfig = new ServiceConfig<Object>();
        serviceConfig.setInterface(this.getInterfaceType());
        serviceConfig.setRef(this.getInstance());
        serviceConfig.setProtocol(PROTOCOL_BUDO_ASYNC);
        serviceConfig.setApplication(APPLICATION_BUDO_ASYNC);
        serviceConfig.setRegistry(NO_REGISTRY);

        if (null == serviceConfig.getParameters()) {
            serviceConfig.setParameters(new HashMap<String, String>());
        }

        String asyncRepositoryBeanName = this.getAsyncRepositoryBeanName();
        if (null == asyncRepositoryBeanName || asyncRepositoryBeanName.isEmpty()) {
            throw new IllegalArgumentException("#58 asyncRepositoryBeanName is null, this=" + this);
        }

        serviceConfig.getParameters().put(AsyncRepository.ASYNC_REPOSITORY_BEAN_NAME, asyncRepositoryBeanName);
        serviceConfig.getParameters().put(AsyncRepository.DESTINATION_NAME, this.destinationName());
        serviceConfig.getParameters().put(Constants.SERIALIZATION_KEY, this.getSerialization());

        serviceConfig.export();
        log.info("#77 export async service, interfaceType=" + this.getInterfaceType() + ", instance=" + this.getInstance() //
                + ", asyncRepositoryBeanName=" + asyncRepositoryBeanName);
    }

    private String destinationName() {
        Class<?> interfaceType = this.getInterfaceType();
        if (null == interfaceType) {
            throw new IllegalArgumentException("#72 interfaceType is null, this=" + this);
        }

        return StringUtil.isEmpty(this.getDestinationName()) //
                ? "budo-async-" + interfaceType.getName() //
                : this.getDestinationName();
    }
}